﻿using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Dude_Platformer.Weapon
{
    public enum AmmoType
    {
        PlayerAmmo,
        EnemyAmmo
    }
    /// <summary>
    /// An Ammunition.
    /// </summary>
    public class Ammo
    {
        public Level Level
        {
            get { return level; }
        }
        Level level;

        public Vector2 Position
        {
            get { return position; }
        }
        Vector2 position;

        public AmmoType Type
        {
            get { return type; }
        }
        AmmoType type;

        private Rectangle localBounds;
        /// <summary>
        /// Gets a rectangle which bounds this object.
        /// </summary>
        public Rectangle BoundingRectangle;

        public void UpdateBoundingRectangle()
        {
            int left = (int)Math.Round(Position.X - sprite.Origin.X) + localBounds.X;
            int top = (int)Math.Round(Position.Y - sprite.Origin.Y) + localBounds.Y;

            BoundingRectangle = new Rectangle(left, top, localBounds.Width, localBounds.Height);
        }


        // Animations
        private Animation movingAnimation;
        private Animation explodeAnimation;
        private AnimationPlayer sprite;

        public Int32 Damage;

        public FaceDirection Direction {
            get { return direction; }
        }
        private FaceDirection direction;

        public Boolean explode = false;
        private Single collisionTime = 0;
        private Single lifeTime = 0;
        private const Single EXPLODING_TIME = 1;
        private const Single LIVING_TIME = 2;
#if ZUNE
        private const float MoveSpeed = 128.0f;
#else
        private const float MoveSpeed = 512.0f;
#endif

        /// <summary>
        /// Constructs a new Bullet.
        /// </summary>
        internal Ammo(Level level, AmmoType type, Vector2 position, string spriteSet, FaceDirection direction)
        {
            this.type = type;
            this.lifeTime = 0;
            this.level = level;
            this.position = position;
            this.direction = direction;

            LoadContent(spriteSet);

            level.addAmmo(this);
        }

        /// <summary>
        /// Loads a particular sprite sheet and sounds.
        /// </summary>
        public void LoadContent(string spriteSet)
        {
            // Load animations.
            spriteSet = "Sprites/" + spriteSet + "/";
            movingAnimation = new Animation(Level.Content.Load<Texture2D>(spriteSet + "BulletMoving"), 0.1f, true);
            explodeAnimation = new Animation(Level.Content.Load<Texture2D>(spriteSet + "BulletExploding"), 0.15f, false);
            sprite.PlayAnimation(explodeAnimation);

            // Calculate bounds within texture size.
            int width = (int)(movingAnimation.FrameWidth * 0.35);
            int left = (movingAnimation.FrameWidth - width) / 2;
            int height = (int)(movingAnimation.FrameWidth * 0.7);
            int top = movingAnimation.FrameHeight - height;
            localBounds = new Rectangle(left, top, width, height);
        }


        /// <summary>
        /// Paces back and forth along a platform, waiting at either end.
        /// </summary>
        public void Update(GameTime gameTime)
        {
            float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;

            // Calculate tile position based on the side we are walking towards.
            float posX = Position.X + localBounds.Width / 2 * (int)direction;
            int tileX = (int)Math.Floor(posX / Tile.Width) - (int)direction;
            int tileY = (int)Math.Floor(Position.Y / Tile.Height);


            if (explode)
            {
                if (collisionTime < EXPLODING_TIME)
                {
                    collisionTime += elapsed;
                }
                else
                {
                    level.RemoveAmmo(this);
                    return;
                }
            }
            else
            {
                lifeTime += elapsed;
                if (lifeTime >= LIVING_TIME)
                {
                    level.RemoveAmmo(this);
                    return;
                }
                UpdateBoundingRectangle();
                // If we are about to run into a wall, explode.
                if (Level.GetCollision(tileX + (int)direction, tileY) == TileCollision.Impassable)
                {
                    explode = true;
                }
                else
                {
                    // Move in the current direction.
                    Vector2 velocity = new Vector2((int)direction * MoveSpeed * elapsed, 0.0f);

                    position = position + velocity;
                }
            }
        }

        /// <summary>
        /// Draws the animated bullet.
        /// </summary>
        public void Draw(GameTime gameTime, SpriteBatch spriteBatch)
        {
            // Stop running when the game is paused or before turning around.
            if (!Level.Player.IsAlive ||
                Level.ReachedExit ||
                //Level.TimeRemaining == TimeSpan.Zero ||
                explode)
            {
                sprite.PlayAnimation(explodeAnimation);
            }
            else
            {
                sprite.PlayAnimation(movingAnimation);
            }

            SpriteEffects flip = direction > 0 ? SpriteEffects.FlipHorizontally : SpriteEffects.None;
            sprite.Draw(gameTime, spriteBatch, Position, flip);
        }
    }
}
